package leetcode;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 题目：
 * <p>
 * 有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C
 * <p>
 * 要求, 同时启动三个线程, 按顺序输出ABC, 循环10次
 *
 * @date 2020/3/10 23:36
 */
public class Code1114_PrintInOrder implements Runnable {
    private static Lock lock = new ReentrantLock();
    private static Condition condition = lock.newCondition();

    private String name;
    private Code1114_PrintInOrder next;
    private boolean execute;

    public Code1114_PrintInOrder(String name, boolean execute) {
        this.name = name;
        this.execute = execute;
    }

    public void run() {
        lock.lock();
        try {
            while (true) {
                if (execute) {
                    print();
                    execute = false;
                    next.setExecute(true);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    condition.signalAll();
                    //
                    break;
                } else {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }

    public void print() {
        System.out.println(name);
    }

    public void setExecute(boolean execute) {
        this.execute = execute;
    }

    public void setNext(Code1114_PrintInOrder next) {
        this.next = next;
    }


    public static void main(String[] args) {
        // 使用循环可以不局限于只有3个线程 交替, 任意多个都可以.
        Code1114_PrintInOrder a = new Code1114_PrintInOrder("A", true);
        Code1114_PrintInOrder b = new Code1114_PrintInOrder("B", false);
        Code1114_PrintInOrder c = new Code1114_PrintInOrder("C", false);

        a.setNext(b);
        b.setNext(c);
        c.setNext(a);

        ExecutorService executor = Executors.newFixedThreadPool(3);// 通过线程池执行
        for (int i = 0; i < 3; i++) {
            executor.execute(a);
            executor.execute(b);
            executor.execute(c);
        }
        executor.shutdown();//关闭线程池
    }
}
